module Hexena.Cmds.EntropyCalc (run) where

import Data.Array.Unboxed
import Data.Word
import qualified Data.ByteString.Lazy as L
import Data.Packed.Vector
import Data.Packed.Matrix
import Text.Printf

--import MathStatistics
import Hexena.MZHeader
import Hexena.PEHeader
import Hexena.Math.Statistics

formatList :: [Double] -> [String]
formatList = map (printf "%13.7e")

formatProbs :: Probabilities -> [String]
formatProbs = formatList . elems

output :: Histogram -> IO ()
output h = putStrLn $ printf "  %g\t%s" entro probs
  where probs = unwords $ formatProbs $ histToProbability h
        entro = calculateE h

printMean :: Matrix Double -> IO ()
printMean m = do
  putStrLn "MEAN/STDDEV:"
  putStrLn $ printf "  %13d\t\t%s" (0::Int) $ unwords $ formatList means
  putStrLn $ printf "  %13d\t\t%s" (0::Int) $ unwords $ formatList stddevs
      where mest = calcStdDev m
            means = map fst mest
            stddevs = map snd mest

fileReader :: FilePath -> IO [Word8]
fileReader fn = L.readFile fn >>= \contents -> return $ L.unpack contents

runner :: FilePath -> IO (Histogram, Histogram)          
runner fn = do
        putStr $ printf "%32s:\t" fn
        content <- fileReader fn
        hist <- calcHist content
        histC <- calcHist $ rleBS content
        _ <- r hist histC content
        return (hist, histC)
     where
        r hist histC content =
           let p = calculateE hist
               pC = calculateE histC
               pe = readPEFrom $ L.pack content
               mzd = mzDistance content
               s = peNumberOfSections pe
           in printf "%13.7e %13.7e %13.7e %d\n" p pC mzd s
        

run :: FilePath -> Bool -> IO ()
run fn True = do 
        (h, hC) <- runner fn
        output h
        output hC
        printMean . fromRows . return . fromList $ elems (histToProbability h) ++ elems (histToProbability hC)
run fn False = runner fn >> putChar '\n'
